#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <QMessageBox>
#include <QThread>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QString style;
    if(loadStyle(style)){
        this->setStyleSheet(style);
    }

    mModel = new QStandardItemModel(this);
    mModel->setHorizontalHeaderLabels(QStringList()
                                            <<QString::fromUtf8("表头")
                                            );

    mSortModel=new SortFilterProxyModel(this);
    mSortModel->setSourceModel(mModel);
    ui->tvcsv->setModel(mSortModel);
}

MainWindow::~MainWindow()
{
    delete ui;
}

//加载样式
bool MainWindow::loadStyle(QString& styleSheet){
    QString path = QCoreApplication::applicationDirPath();
    path+="/style.qss";

    qDebug()<<path;
    // 创建QFile对象并指定QSS文件的路径
    QFile file(path);

    // 打开文件
    if (file.open(QFile::ReadOnly))
    {
        // 读取文件内容到QString
        styleSheet= QString(file.readAll());
        return true;
    }
    return false;
}


void MainWindow::on_btnModel_clicked()
{
    QString path = QCoreApplication::applicationDirPath();
    QString filePath = QFileDialog::getOpenFileName(nullptr, QObject::tr("打开文件"), path, QObject::tr("文本文档 Files (*.txt)"));

    if (!filePath.isEmpty()) {
        QFile file(filePath); // 创建文件对象并指定文件路径
        if (!file.open(QIODevice::ReadOnly)) { // 尝试打开文件以写入数据
            return; // 如果无法打开文件，‌则返回并不执行后续操作
        }
        QTextStream in(&file);
        in.setCodec("UTF-8");
        QString model = in.readAll();
        file.close();

        ui->lblModel->clear();
        ui->lblModel->setText(model);

        baseSQL=model;
        baseSQL=baseSQL.replace("\r\n","\n");
    }
}

void MainWindow::on_btnCsv_clicked()
{
    if(baseSQL.isEmpty()){
        QMessageBox msgBox;
        msgBox.setWindowTitle("错误");
        msgBox.setText("请先加载模板文件");
        msgBox.setStandardButtons(QMessageBox::Yes);

        msgBox.exec();

        return;
    }
    QString path = QCoreApplication::applicationDirPath();
    QString filePath = QFileDialog::getOpenFileName(nullptr, QObject::tr("打开文件"), path, QObject::tr("CSV文档 Files (*.csv)"));

    if (!filePath.isEmpty()) {
        QFile file(filePath); // 创建文件对象并指定文件路径
        if (!file.open(QIODevice::ReadOnly)) { // 尝试打开文件以写入数据
            return; // 如果无法打开文件，‌则返回并不执行后续操作
        }

        QTextStream in(&file);
        in.setCodec("UTF-8");

        QString strHeader=in.readLine();
        title=strHeader.split(",");
        file.close();

        if(title.empty()){
            QMessageBox msgBox;
            msgBox.setWindowTitle("错误");
            msgBox.setText("csv文件无表头,第一行必须是表头");
            msgBox.setStandardButtons(QMessageBox::Yes);

            msgBox.exec();

            return;
        }
        mModel->clear();
        mModel->setHorizontalHeaderLabels(title);
        csvFile=filePath;

        QThread* thread = QThread::create(MainWindow::taskViewItem,filePath, this);
        thread->start();
    }
}

void MainWindow::addCsvItem(QStringList field, int count){
    if(field.length()==title.size()){
        QList<QStandardItem*> ls;
        for(int i=0;i<field.length();i++){
            bool isNumber{false};
            field[i].toDouble(&isNumber);
            QStandardItem* item=new QStandardItem();
            item->setText(field[i]);
            item->setData(isNumber?1:0);//1/int,2/double
            ls<<item;
        }

        mModel->appendRow(ls);

        fields.push_back(field);
        if(fields.size()>100){
            //转换成SQL语句
            createSql();
        }
    }else{
        QString txt=csvFile;
        txt+=" 第";
        txt+=QString::number(count+1);
        txt+="行,数据有问题！！！";
        QMessageBox msgBox;
        msgBox.setWindowTitle("错误");
        msgBox.setText(txt);
        msgBox.setStandardButtons(QMessageBox::Yes);

        msgBox.exec();
    }
}

void MainWindow::addCsvItemFinish(){
    if(!fields.empty()){
        //转换成SQL语句
        createSql();
    }
}

//生成sql语句并保存
void MainWindow::createSql(){
    std::vector<QString> vecSql;
    for(auto it=fields.begin();it!=fields.end();++it){
        auto sql=baseSQL;
        QVector<int> placeholderPositions;

        auto field=*it;
        // 查找所有%数字的位置
        for(int i = 0; i < sql.length()-1; ++i) {
            if(sql[i] == '%' && sql[i+1].isDigit()) {
                auto n=sql.mid(i+1,1).toInt();
                if(n>=1&&n<field.size()){
                    sql.replace(i, 2, field[n-1]);
                }
            }
        }
        ui->lblSql->setText(sql);
        vecSql.push_back(sql);
    }

    fields.clear();

    QString path = QCoreApplication::applicationDirPath();
    path+="/my.sql";
    QFile file(path);
    if (file.open(QIODevice::Append | QIODevice::Text)) {
        QTextStream out(&file);
        out.setCodec("UTF-8");
        for(auto it=vecSql.begin();it!=vecSql.end();++it){
            out<<(*it)<<endl<<endl<<endl<<endl;
        }
    }
    file.close();
}

void MainWindow::taskViewItem(const QString& path, QObject* obj){
    QFile file(path); // 创建文件对象并指定文件路径
    if (!file.open(QIODevice::ReadOnly)) { // 尝试打开文件以写入数据
        return; // 如果无法打开文件，‌则返回并不执行后续操作
    }

    QTextStream in(&file);
    in.setCodec("UTF-8");

    int count{0};
    while (!in.atEnd()) {
        count++;


        QString line = in.readLine();
        if(count==1){
            continue;
        }

        QStringList fields;
        bool inQuotes = false;
        QString temp;

        for(int i = 0; i < line.length(); i++) {
            if(line[i] == '\"') {
                inQuotes = !inQuotes;
            } else if(line[i] == ',' && !inQuotes) {
                fields.append(temp);
                temp.clear();
            } else {
                temp += line[i];
            }
        }

        fields.append(temp);
        QMetaObject::invokeMethod(obj,"addCsvItem", Qt::QueuedConnection,Q_ARG(QStringList,fields),Q_ARG(int,count));

        QThread::msleep(100);
    }
    file.close();
    QMetaObject::invokeMethod(obj,"addCsvItemFinish", Qt::QueuedConnection);
}
